package com.boarsoft.flow.core;

import java.util.Map;
import java.util.concurrent.Future;

import com.boarsoft.flow.store.SimpleFlowPersister;

/**
 * 流程引擎对外接口
 * 
 * @author Mac_J
 *
 */
public interface SimpleFlowEngine {
	/**
	 * 检查流程定义Bean是否存在
	 * 
	 * @param flowId
	 *            流程定义的spring bean id
	 * @return
	 */
	boolean exists(String flowId);

	/**
	 * 启动流程
	 * 
	 * @param flowId
	 *            流程定义的spring bean id
	 * @param data
	 *            入参
	 * @return
	 * @throws Throwable
	 */
	SimpleFlow start(String flowId, Object data) throws Throwable;

	/**
	 * 启动流程
	 * 
	 * @param flowId
	 *            流程定义的spring bean id
	 * @param data
	 *            入参
	 * @param entry
	 *            指定从流程中的哪个步骤开始，不指定时，将从头开始运行
	 * @return
	 * @throws Throwable
	 */
	SimpleFlow start(String flowId, Object data, String entry) throws Throwable;

	/**
	 * 启动流程
	 * 
	 * @param flowId
	 *            流程定义的spring bean id
	 * @param id
	 *            指定流程实例的ID
	 * @param data
	 *            入参
	 * @param entry
	 *            指定从流程中的哪个步骤开始，不指定时，将从头开始运行
	 * @return
	 * @throws Throwable
	 */
	SimpleFlow start(String flowId, String id, Object data, String entry) throws Throwable;

	/**
	 * 启动流程
	 * 
	 * @param flow
	 *            流程实例对象
	 * @return
	 * @throws Throwable
	 */
	SimpleFlow start(SimpleFlow flow) throws Throwable;

	/**
	 * 启动流程
	 * 
	 * @param flow
	 *            流程实例对象
	 * @param entry
	 *            指定从流程中的哪个步骤开始，不指定时，将从头开始运行
	 * @return
	 * @throws Throwable
	 */
	SimpleFlow start(SimpleFlow flow, String entry) throws Throwable;

	/**
	 * 续跑流程
	 * 
	 * @param flowId
	 *            流程定义的spring bean id
	 * @param id
	 *            指定流程实例的ID
	 * @param exData
	 *            续跑时的入参，会覆盖流程原来的数据
	 * @return
	 * @throws Throwable
	 */
	SimpleFlow resume(String flowId, String id, Object exData) throws Throwable;

	/**
	 * 续跑流程
	 * 
	 * @param flow
	 *            流程实例对象
	 * @return
	 * @throws Throwable
	 */
	SimpleFlow resume(SimpleFlow flow) throws Throwable;

	/**
	 * 获取流程实例
	 * 
	 * @param flowId
	 *            流程定义的spring bean id
	 * @param exeId
	 *            流程实例的ID
	 * @return
	 * @throws Throwable
	 */
	SimpleFlow getFlow(String flowId, String exeId) throws Throwable;

	/**
	 * 中断流程实例
	 * 
	 * @param flow
	 *            流程实例对象
	 * @return
	 */
	boolean stop(SimpleFlow flow);

	/**
	 * 续跑流程
	 * 
	 * @param flow
	 *            流程实例对象
	 * @param exData
	 *            续跑时的入参，会覆盖流程原来的数据
	 * @return
	 * @throws Throwable
	 */
	SimpleFlow resume(SimpleFlow flow, Object exData) throws Throwable;

	/**
	 * 获取当前流程引擎实例的归属（如：系统、分类）
	 * 
	 * @return
	 */
	String getCatalog();

	/**
	 * 异步执行流程，不关心结果
	 * 
	 * @param flow
	 */
	void execute(SimpleFlow flow);

	/**
	 * 异步执行流程，返回Future对象，调用其get方法会阻塞，直到结果返回
	 * 
	 * @param r
	 * @return future
	 */
	Future<SimpleFlow> submit(SimpleFlow r);

	/**
	 * 异步执行流程，不关心结果
	 * 
	 * @param flowId
	 *            流程定义的spring bean id
	 * @param id
	 *            指定流程实例的ID
	 * @param params
	 *            入参
	 * @param entry
	 *            指定从流程中的哪个步骤开始，不指定时，将从头开始运行
	 */
	void execute(String flowId, String id, Object params, String entry);

	/**
	 * 异步执行流程，返回Future结果
	 * 
	 * @param flowId
	 *            流程定义的spring bean id
	 * @param id
	 *            指定流程实例的ID
	 * @param params
	 *            入参
	 * @param entry
	 *            指定从流程中的哪个步骤开始，不指定时，将从头开始运行
	 * @return future
	 */
	Future<SimpleFlow> submit(String flowId, String id, Object params, String entry);

	/**
	 * 根据流程定义，创建流程实例
	 * 
	 * @param flowId
	 * 
	 * @return
	 */
	SimpleFlow create(String flowId);

	/**
	 * 异步执行流程，不关心结果
	 * 
	 * @param flowId
	 *            流程定义的spring bean id
	 * @param id
	 *            指定流程实例的ID
	 * @param params
	 *            入参
	 */
	void execute(String flowId, String id, Object params);

	/**
	 * 清除流程和对象缓存，暂停对外服务
	 */
	void close();

	/**
	 * 恢复对外服务
	 */
	void open();

	/**
	 * 返回计时中（运行中）的任务
	 * 
	 * @return
	 */
	Map<String, Map<String, SimpleFlow>> getTimeMap();

	/**
	 * 返回当前流程引擎实例所用的持久化器
	 * 
	 * @return
	 */
	SimpleFlowPersister getPersister();

	/**
	 * 打开全局监控开关
	 */
	void watch();

	/**
	 * 开启对指定流程的监控，并设置采集频率
	 * 
	 * @param flowId
	 *            流程定义的spring bean id
	 * @param ratio
	 *            采集频率
	 */
	void watch(String flowId, int ratio);

	/**
	 * 关闭全局监控开关
	 */
	void ignore();

	/**
	 * 取消对指定flow的采样
	 * 
	 * @param flowId
	 *            流程定义的spring bean id
	 */
	void ignore(String flowId);

	/**
	 * 返回流程实例定义模板
	 * 
	 * @param flowId
	 * @return
	 */
	SimpleFlow getFlow(String flowId);

	/**
	 * 将流程与当前线程解绑，清理线程变量
	 * 
	 * @param f
	 */
	void unmark(SimpleFlow f);

	/**
	 * 将流程与当前线程绑定，设置线程变量
	 * 
	 * @param f
	 */
	void mark(SimpleFlow f);

}
